package com.ups.singlearner;

import java.util.ArrayList;

public class Composition {
	private static Composition composition = null;
	private ArrayList<ComposedNote> notes;
	private ArrayList<ComposedNote> sungNotes;
	private LineProgress lineProgress;

	private Composition() {
		notes = new ArrayList<ComposedNote>();
		sungNotes = new ArrayList<ComposedNote>();
		lineProgress = new LineProgress();
	}

	public static Composition getInstance() {
		if (composition == null)
			synchronized (Composition.class) {
				if (composition == null) {
					composition = new Composition();
				}
			}

		return composition;
	}

	public void addNote(ComposedNote n) {
		ArrayList<ComposedNote> toRemove = new ArrayList<ComposedNote>();

		synchronized (composition) {

			// check if the new note isn't in conflict with previous added, if
			// so modify them
			for (ComposedNote n2 : notes) {

				if (n.getBegin() <= n2.getBegin()
						&& (n.getBegin() + n.getDuration()) >= n2.getBegin()
								+ n2.getDuration()) {
					toRemove.add(n2);
					continue;
				}

				if (n.getBegin() > n2.getBegin() + n2.getDuration()) {
					// begin after the end, don't change
				} else {
					if (n.getBegin() < n2.getBegin()) {
						// don't care
					} else {
						// need to cut end of n2
						n2.setDuration(n.getBegin() - n2.getBegin());
					}
				}

				if (n.getBegin() + n.getDuration() <= n2.getBegin()) {
					// end before n2 begin, don't change
				} else {
					if (n.getBegin() + n.getDuration() > n2.getBegin()
							+ n2.getDuration()) {
						// don't care
					} else {
						// need to cut begin of n2
						n2.setDuration(n2.getDuration()
								- (n.getBegin() + n.getDuration() - n2
										.getBegin()));
						n2.setBegin(n.getBegin() + n.getDuration());
					}
				}

			}
			notes.add(n);
			notes.removeAll(toRemove);
		}
	}

	public void addSungNote(ComposedNote n) {
		sungNotes.add(n);
	}

	public ArrayList<ComposedNote> getNotes() {
		return notes;
	}

	public ArrayList<ComposedNote> getSungNotes() {
		return sungNotes;
	}

	public void clear() {
		synchronized (composition) {
			notes.clear();
			sungNotes.clear();
			lineProgress = new LineProgress();
		}
	}

	public LineProgress getLineProgress() {
		return lineProgress;
	}

	public void setLineProgress(LineProgress lineProgress) {
		this.lineProgress = lineProgress;
	}
}
